﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using ForfiterStockInfo.Entities;
using System.Collections.ObjectModel;

namespace ForfiterStockInfo.Client
{
    public partial class MainWindow : Form
    {
        bool _dataModyfingInProgress;
        string _fullErrorMessage;
        private TimedHTMLAdapter _timedHTMLAdapter = new TimedHTMLAdapter(60000, "http://www.bankier.pl/inwestowanie/notowania/akcje.html");

        delegate void SetErrorMessageCallback(bool isError, string message, string fullMessage);

        public MainWindow()
        {
            InitializeComponent();
            _timedHTMLAdapter.DownloadCompleted += TimedHTMLAdapter_DownloadCompleted;
        }

        public forfiterDataSet.StockRow SelectedStock
        {
            get
            {
                var dataRowView = listBoxStock.SelectedItem as DataRowView;
                if (dataRowView == null)
                    return null;
                return dataRowView.Row as forfiterDataSet.StockRow;
            }
        }

        private void GetChartData()
        {
            if (SelectedStock == null)
                return;

            chartPrice.Series[0].Points.Clear();
            chartVolume.Series[0].Points.Clear();
            forfiterDataSet.RecordDataTable records = new forfiterDataSet.RecordDataTable();
            recordTableAdapter.FillByStock(records, SelectedStock.Id);

            decimal minPrice = decimal.MaxValue;
            decimal maxPrice = 0;
            DateTime minDate = DateTime.MaxValue;
            DateTime maxDate = DateTime.MinValue;
            int lastVolume = 0;
            foreach (var record in records)
            {
                if (record.Date.Date != dateTimePickerDay.Value.Date)
                    continue;

                if (minPrice > record.Price)
                    minPrice = record.Price;

                if (maxPrice < record.Price)
                    maxPrice = record.Price;

                if (minDate > record.Date)
                    minDate = record.Date;

                if (maxDate < record.Date)
                    maxDate = record.Date;
                
                chartPrice.Series[0].Points.AddXY(record.Date, record.Price);
                chartVolume.Series[0].Points.AddXY(record.Date, record.Volume - lastVolume);
                lastVolume = record.Volume;
            }

            chartPrice.ChartAreas[0].AxisY.Minimum = (double)(minPrice);
            chartPrice.ChartAreas[0].AxisY.Maximum = (double)(maxPrice);
            double yInterval = (double)((maxPrice - minPrice) / 10);
            if (yInterval < 0.01)
                yInterval = 0.01;
            chartPrice.ChartAreas[0].AxisY.Interval = yInterval;
        }

        private void SetErrorMessage(bool isError, string message, string fullMessage)
        {
            if (statusStrip1.InvokeRequired)
            {
                SetErrorMessageCallback d = new SetErrorMessageCallback(SetErrorMessage);
                Invoke(d, new object[] { isError, message, fullMessage });
            }
            else
            {
                if (isError)
                    toolStripStatusLabelError.ForeColor = Color.Red;
                else
                    toolStripStatusLabelError.ForeColor = Color.Green;

                toolStripStatusLabelError.Text = message;
                _fullErrorMessage = fullMessage;
            }
        }

        private void TimedHTMLAdapter_DownloadCompleted(object sedner, DownloadStringCompletedEventArgs e)
        {
            if (_dataModyfingInProgress)
                return;
            _dataModyfingInProgress = true;

            try
            {
                var records = BankierParser.GetRecords(e.Result);

                foreach (var r in records)
                {
                    var stockRow = forfiterDataSet.Stock.FirstOrDefault(sr => sr.Name == r.Stock.Name);
                    if (stockRow == null)
                        stockRow = forfiterDataSet.Stock.AddStockRow(r.Stock.Name, r.Stock.FullName);

                    forfiterDataSet.Record.AddRecordRow(stockRow, r.Price, r.ChangePrice, r.ChangePercent, r.Volume, r.Turnover, r.OpeningPrice, r.MaxPrice, r.MinPrice, DateTime.Now);
                }

                stockTableAdapter.Update(forfiterDataSet);
                recordTableAdapter.Update(forfiterDataSet);                
                SetErrorMessage(false, "Dane pobrane", string.Empty);
            }
            catch (Exception ex)
            {
                SetErrorMessage(true, "Błąd podczas pobierania danych", ex.Message);
            }
            finally
            {
                _dataModyfingInProgress = false;
            }
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            stockTableAdapter.FillByAllStocks(this.forfiterDataSet.Stock);
            _timedHTMLAdapter.Start();
        }

        private void dateTimePickerDay_ValueChanged(object sender, EventArgs e)
        {
            GetChartData();
        }

        private void listBoxStock_SelectedIndexChanged(object sender, EventArgs e)
        {
            GetChartData();
        }
    }
}
